#include "Dispatch.h"

Dispatch::Dispatch(void)
{
	//
	//Loads various values and creates new objects
	//
	state = TITLEMENU;
	game = new Game();
	render = new Render();
	
	
	//Makes new menus for use later
	TitleMenu *temp = new TitleMenu(); 
	menus.push_back(temp);
	FrontMenu *temp1 = new FrontMenu(); 
	menus.push_back(temp1);
	DifficultySelectMenu *temp2 = new DifficultySelectMenu(); 
	menus.push_back(temp2);
	DifficultySelectMenu *temp3 = new DifficultySelectMenu(); 
	menus.push_back(temp3);
	DifficultySelectMenu *temp4 = new DifficultySelectMenu(); 
	menus.push_back(temp4);
	DifficultySelectMenu *temp5 = new DifficultySelectMenu(); 
	menus.push_back(temp5);
	DifficultySelectMenu *temp6 = new DifficultySelectMenu(); 
	menus.push_back(temp6);
	DifficultySelectMenu *temp7 = new DifficultySelectMenu(); 
	menus.push_back(temp7);
	DifficultySelectMenu *temp8 = new DifficultySelectMenu(); 
	menus.push_back(temp8);
	DifficultySelectMenu *temp9 = new DifficultySelectMenu(); 
	menus.push_back(temp9);
	PauseMenu *temp10 = new PauseMenu(); 
	menus.push_back(temp10);
	DeathMenu *temp11 = new DeathMenu(); 
	menus.push_back(temp11);
	StageSelect *temp12 = new StageSelect(); 
	menus.push_back(temp12);
	hud = new Hud();
	//sets arbitrary values to start off with for safety reasons
	level = 0;
	diff = MEDIUM;
	
}

Dispatch::~Dispatch(void)
{
}

void Dispatch::loadTextures(){
	//
	//Loads all textures associated with various things
	//
	render->PrepTextures();
	hud->loadTextures();
	for(int i =0; i < 2;i++){
	menus[i]->loadTextures();
	}
	menus[2]->loadTextures(NOTDIFFICULT);
	menus[3]->loadTextures(EASY);
	menus[4]->loadTextures(MEDIUM);
	menus[5]->loadTextures(HARD);
	menus[6]->loadTextures(EASYENDING);
	menus[7]->loadTextures(MEDIUMENDING);
	menus[8]->loadTextures(HARDENDING);
	menus[9]->loadTextures(TUTOR);
	menus[10]->loadTextures();
	menus[11]->loadTextures();
	menus[12]->loadTextures();



}


void Dispatch::loadLevel(char * filename){

	//
	//Loads a level with a filename changes the state and gets render ready to draw
	//
	state = GAME;
	game->loadLevel( filename);
	render->UpdateMap(game->getMap(), game->getMaxX(), game->getMaxY(), game->getMaxZ());
	//more things unique to dispatch needed here such as timer
}

void Dispatch::reloadLevel(){
	//
	//Reloads the current level
	//
	state = GAME;
	game->restartLevel();
	render->UpdateMap(game->getMap(), game->getMaxX(), game->getMaxY(), game->getMaxZ());
}

void Dispatch::doVictory(){
	//
	//Does different victory conditions based on your current level
	//
	if(diff == NOTDIFFICULT){
		state = STAGESELECT;
	}
	if(level ==1 && diff == EASY){
		loadLevel("easy2.txt");
		level++;
	}
	else if(level ==2 && diff == EASY){
		loadLevel("easy3.txt");
		level++;
	}
	else if(level ==3 && diff == EASY){
		state=ENDINGEASY;
	}
	if(level ==1 && diff == MEDIUM){
		loadLevel("medium2.txt");
		level++;
	}
	else if(level ==2 && diff == MEDIUM){
		loadLevel("medium3.txt");
		level++;
	}
	else if(level ==3 && diff == MEDIUM){
		state=ENDINGMEDIUM;
	}
		if(level ==1 && diff == HARD){
		loadLevel("hard2.txt");
		level++;
	}
	else if(level ==2 && diff == HARD){
		loadLevel("hard3.txt");
		level++;
	}
	else if(level ==3 && diff == HARD){
		state=ENDINGHARD;
	}
	}

void Dispatch::doLoss(){
	//
	//shows the death screen if you have lost
	//
	state = DEATHMENU;
}

void Dispatch::dispatchTimerPulse()
{
	//
	//Gets a timer pulse from Timer and does actions based on current situation
	//
	static int counter = 0;
	//Counter is for intial loading of all textures ie when the game starts
	if (counter == 0){
		loadTextures();
		menus[0]->draw();
		counter++;
	}
	//if you're in game mode, check victory or loss conditions as well as loss by time out condition
	if(state == GAME){
		game->updateGameTimer();

		if(game->isVictory()){
			doVictory();
		}
		if(game->isLoss()){
			doLoss();
		}
		if(game->getStatus()->getCountdown() ==0){
		doLoss();
		}
	}
	
	
}

void Dispatch::doRender(){
	//
	//Renders based on what state the game is
	//
	if(state==GAME){
		render->doRender(game->taitLoc());
		hud->draw(game->getStatus());
	}
	else if(state==PAUSEMENU){
		render->doRender(game->taitLoc());
		hud->draw(game->getStatus());
		menus[10]->draw();
	}
	else if(state==DEATHMENU){
		render->doRender(game->taitLoc());
		hud->draw(game->getStatus());
		menus[11]->draw();
	}
	else if(state == STAGESELECT){
		menus[12]->draw();
	}
	else if(state == TITLEMENU){
		menus[0]->draw();
	}
	else if(state == FRONTMENU){
		menus[1]->draw();
	}
	else if(state == DIFFICULTYSELECT){
		menus[2]->draw();
	}
	else if(state == INTROEASY){
		menus[3]->draw();
	}
	else if(state == INTROMEDIUM){
		menus[4]->draw();
	}
	else if(state == INTROHARD){
		menus[5]->draw();
	}
	else if(state == ENDINGEASY){
		menus[6]->draw();
	}
	else if(state == ENDINGMEDIUM){
		menus[7]->draw();
	}
	else if(state == ENDINGHARD){
		menus[8]->draw();
	}
	else if(state == TUTORIAL){
		menus[9]->draw();
	}


}

void Dispatch::dispatchMouseMotionEvent(int x, int y)
{
	//
	//dispatches mouse motion events (only for game really)
	//
	switch(state)
	{
	case GAME:
		render->changeCamera(x, y);
		break;
	}
}

void Dispatch::dispatchMouseEvent(int button, int state, int x, int y){

	//
	//Dispatches mouse event (currently not used)
	//
	switch(state)
	{
	case MENU:
		break;
	case GAME:
		break;
	case TITLEMENU:
		break;
	}

}

void Dispatch::dispatchKeyboardEvent(unsigned key){
	//
	//Gets a keyboard event and does appropriate actions based on the current state, q will always quit however
	//
	if (key == 'Q' || key == 'q' || key == 27)
			{
				exit(1);
			}

	switch(state){

		case TITLEMENU:
			if (key == 'a' || key == 'A') {
				state=FRONTMENU;
			}
			
			break;

		case FRONTMENU: 
			if (key == '1'){
				state=DIFFICULTYSELECT;
			}
			else if (key == '2'){ 
				state = STAGESELECT;
			}

			else if (key == '3'){ 
			
				state = TUTORIAL;
			}			
			break;

		case STAGESELECT:
			if (key=='b' || key=='B'){
				state=FRONTMENU;
			}
			else if (key=='1'){
				diff = NOTDIFFICULT;
				loadLevel("easy1.txt");
			}
			else if (key=='2'){
				diff = NOTDIFFICULT;
				loadLevel("easy2.txt");
			}
			else if (key=='3'){
				diff = NOTDIFFICULT;
				loadLevel("easy3.txt");
			}
			else if (key=='4'){
				diff = NOTDIFFICULT;
				loadLevel("medium1.txt");
			}
			else if (key=='5'){
				diff = NOTDIFFICULT;
				loadLevel("medium2.txt");
			}
			else if (key=='6'){
				diff = NOTDIFFICULT;
				loadLevel("medium3.txt");
			}
			else if (key=='7'){
				diff = NOTDIFFICULT;
				loadLevel("hard1.txt");
			}
			else if (key=='8'){
				diff = NOTDIFFICULT;
				loadLevel("hard2.txt");
			}
			else if (key=='9'){
				diff = NOTDIFFICULT;
				loadLevel("hard3.txt");
			}

			break;

		case DIFFICULTYSELECT: 
			if (key == '1'|| key=='E'){
				state = INTROEASY;
			}
			else if (key == '2'|| key=='M'){ 
				state = INTROMEDIUM;
			}

			else if (key == '3'|| key=='H'){ 
			
				state = INTROHARD;
			}		
			else if (key=='b' || key=='B'){
				state=FRONTMENU;
			}
			break;


		case INTROEASY: 
			if (key == 'a'|| key=='A'){
				level = 1;
				diff = EASY;
				loadLevel("Easy1.txt");
			}
			else if (key=='b' || key=='B'){
				state=FRONTMENU;
			}
			break;

		case INTROMEDIUM: 
			if (key == 'a'|| key=='A'){
				level = 1;
				diff = MEDIUM;
				loadLevel("Medium1.txt");
			}
			else if (key=='b' || key=='B'){
				state=FRONTMENU;
			}
			break;
		case INTROHARD: 
			if (key == 'a'|| key=='A'){
				level = 1;
				diff = HARD;
				loadLevel("Hard1.txt");
			}
			else if (key=='b' || key=='B'){
				state=FRONTMENU;
			}
			break;

		case ENDINGHARD: 
			if (key == 'a'|| key=='A'){
				state=FRONTMENU;
			}
			break;
		case ENDINGEASY: 
			if (key == 'a'|| key=='A'){
				state=FRONTMENU;
			}
			break;
		case ENDINGMEDIUM: 
			if (key == 'a'|| key=='A'){
				state=FRONTMENU;
			}
			break;
		case TUTORIAL: 
			if (key=='b' || key=='B'){
				state=FRONTMENU;
			}
			break;
		

		case PAUSEMENU:
			if (key=='p' || key=='P'){
				state=GAME;
			}
			else if (key=='b' || key=='B'){
				state=FRONTMENU;
			}
			else if (key == 'r' || key == 'R') {
				reloadLevel();
			}
			break;

		case DEATHMENU:
			if (key=='b' || key=='B'){
				state=FRONTMENU;
			}
			else if (key == 'r' || key == 'R') {
				reloadLevel();
			}
			break;

		case GAME: 
			//
			//Move Controls
			//
			if (key == 'w' || key == 'W'){
				game->moveTait(UP);
			} else if (key == 'a' || key == 'A') {
				game->moveTait(LEFT);

			} else if (key == 's' || key == 'S') {
				game->moveTait(DOWN);

			} else if (key == 'd' || key == 'D') {
				game->moveTait(RIGHT);
			}

			//
			//Equip Controls
			//
			else if (key == '1'){
				game->equipItem(FIREBOOTS);
			}

			else if (key == '2'){
				game->equipItem(FLIPPERS);
			}

			else if (key == '3'){
				game->equipItem(ICESKATES);}

			else if (key == '4'){
				game->equipItem(SUCTIONCUPS);
			}

			else if (key == '5'){
				game->equipItem(LEVITATESANDALS);
			}


			//
			//Function Controls
			//
			else if (key == 'p' || key == 'P') {
				state = PAUSEMENU;
			}
			else if (key == 'o' || key == 'O') {
			}
			else if (key == 'r' || key == 'R') {
				reloadLevel();
			}
			else if (key == 'Q' || key == 'q' || key == 27)
			{
				exit(1);
			}
			else if (key == 'E' || key == 'e')
				render->wheel(1);
			else if (key == 'C' || key == 'c')
				render->wheel(-1);
			break;	
	}

}

void Dispatch::dispatchSpecialKeyboardEvent(int key){
	switch(state){
		case TITLEMENU: 
			if(key==GLUT_KEY_F3){
			cout<<"pressed";
			}
			break;
	}


}